namespace dguUmbracoControls
{
	using System;
	using System.Data;
	using System.Drawing;
	using System.Web;
	using System.Web.UI.WebControls;
	using System.Web.UI.HtmlControls;
	using System.IO;
	using System.Drawing.Drawing2D;
	using System.Drawing.Imaging;
	using System.Xml;
	using System.Xml.XPath;
	
	using ICSharpCode.SharpZipLib.BZip2;
	using ICSharpCode.SharpZipLib.Zip;
	using ICSharpCode.SharpZipLib.Zip.Compression;
	using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
	using ICSharpCode.SharpZipLib.GZip;

	using umbraco.cms.businesslogic;
	using umbraco.cms.businesslogic.media;

	/// <summary>
	///		Summary description for zipUpload.
	/// </summary>
	public partial class zipUpload : System.Web.UI.UserControl
	{
		
		private System.Collections.Hashtable confirmedDirs = new System.Collections.Hashtable();
		private umbraco.BusinessLogic.User u;

		protected void Page_Load(object sender, System.EventArgs e)
		{
			
			this.ID = "dashBoardZipUpload";
			// Put user code to initialize the page here
		}

		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);
		}
		
		/// <summary>
		///		Required method for Designer support - do not modify
		///		the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{

		}
		#endregion

		private Media checkPath(umbraco.cms.businesslogic.CMSNode parent, string DirName, umbraco.BusinessLogic.User u, int folderNodeTypeId) 
		{
			if (parent.Children.Length > 0) 
			{
				foreach(CMSNode c in parent.Children) 
				{
					if (c.Text.ToLower() == DirName.ToLower())
						return new Media(c.Id);
				}
			} 

			Media m =  umbraco.cms.businesslogic.media.Media.MakeNew(
					DirName, new umbraco.cms.businesslogic.media.MediaType(folderNodeTypeId), u, parent.Id);
			// Put directories on top
			m.sortOrder = 0;
			return m;

		}

		protected void Button1_Click(object sender, System.EventArgs e)
		{

			string uploaded = "";

			// Load config settings
			XmlDocument x = new XmlDocument();
			x.Load(Server.MapPath(umbraco.GlobalSettings.StorageDirectory + "\\umbDashboard.xml"));
			int fileNodeTypeId = int.Parse(x.SelectSingleNode("/dashboardConfig/zipUpload/fileNodeTypeId").FirstChild.Value);
			int imageNodeTypeId = int.Parse(x.SelectSingleNode("/dashboardConfig/zipUpload/imageNodeTypeId").FirstChild.Value);
			int folderNodeTypeId = int.Parse(x.SelectSingleNode("/dashboardConfig/zipUpload/folderNodeTypeId").FirstChild.Value);
			string imageExtensions = "," + x.SelectSingleNode("/dashboardConfig/zipUpload/imageFileExtensions").FirstChild.Value + ",";
			string _thumbnails = "";
			if (x.SelectSingleNode("/dashboardConfig/zipUpload/thumbnailSizes") != null)
				_thumbnails = x.SelectSingleNode("/dashboardConfig/zipUpload/thumbnailSizes").FirstChild.Value;

			// Get the current user
			umbraco.BasePages.UmbracoEnsuredPage up = new umbraco.BasePages.UmbracoEnsuredPage();
			u = up.getUser();

			// Fetch the node
			umbraco.cms.businesslogic.media.Media m;
			if (folderid.Value != "")
				m = new umbraco.cms.businesslogic.media.Media(int.Parse(folderid.Value));
			else
				m = Media.GetRootMedias()[0];

			string zipName = Server.MapPath(umbraco.GlobalSettings.StorageDirectory) + "\\" + Guid.NewGuid().ToString() + ".zip";
			inputFile2.MoveTo(zipName, Brettle.Web.NeatUpload.MoveToOptions.Overwrite);
//			file1.PostedFile.SaveAs(zipName);
			
			// Create temporary directory for stored zip contents
			string tempDir = Server.MapPath(umbraco.GlobalSettings.StorageDirectory) + "\\" + Guid.NewGuid().ToString();
			Directory.CreateDirectory(tempDir);

			// Unzip
			ZipInputStream s = new ZipInputStream(File.OpenRead(zipName));
		
			// initialize root
			Media currentParent = m;




			ZipEntry theEntry;
			while ((theEntry = s.GetNextEntry()) != null) 
			{
				string directoryName = Path.GetDirectoryName(theEntry.Name);
				string fileName      = Path.GetFileName(theEntry.Name);


				// Check dir
				if (directoryName == "")
					currentParent = m;
				else if (confirmedDirs.ContainsKey(directoryName.ToLower()))
					currentParent = (Media) confirmedDirs[directoryName.ToLower()];
				else  
				{
					currentParent = m;
					string[] dirs = directoryName.Split("\\".ToCharArray());
					foreach(string d in dirs) 
					{
						currentParent = checkPath(currentParent, d, u, folderNodeTypeId);
					}
					confirmedDirs.Add(directoryName.ToLower(), currentParent);
				} 

				if (fileName != String.Empty) 
				{
					FileStream streamWriter = File.Create(tempDir + "\\" + fileName);

					int size = 2048;
					byte[] data = new byte[2048];
					while (true) 
					{
						size = s.Read(data, 0, data.Length);
						if (size > 0) 
						{
							streamWriter.Write(data, 0, size);
						} 
						else 
						{
							break;
						}
					}

					streamWriter.Close();

					// File created, add it to the media library
					umbraco.cms.businesslogic.media.Media newMedia;
					if (imageExtensions.IndexOf(","+Path.GetExtension(theEntry.Name).Replace(".", "")+",") > 0) 
						newMedia = umbraco.cms.businesslogic.media.Media.MakeNew(fileName, new umbraco.cms.businesslogic.media.MediaType(imageNodeTypeId), u, currentParent.Id);
					else
						newMedia = umbraco.cms.businesslogic.media.Media.MakeNew(fileName, new umbraco.cms.businesslogic.media.MediaType(fileNodeTypeId), u, currentParent.Id);

					string newName = newMedia.UniqueId.ToString() + "-" + fileName;
					File.Move(tempDir + "\\" + fileName, Server.MapPath("/media") + "\\" + newName);
					
					// Add to list...
					uploaded += "- " + theEntry.Name + "<br/>";
					
					// Save filename
					newMedia.getProperty("umbracoFile").Value = "/media/" + newName;

					// Save type
					newMedia.getProperty("umbracoExtension").Value = Path.GetExtension(theEntry.Name).Replace(".", "");

					// Save size
					newMedia.getProperty("umbracoBytes").Value = theEntry.Size;

					try 
					{
						if (imageExtensions.IndexOf(","+Path.GetExtension(theEntry.Name).Replace(".", "")+",") > 0) 
						{
							FileStream fs = new FileStream(Server.MapPath("/media") + "\\" + newName, 
								FileMode.Open, FileAccess.Read, FileShare.Read);
        

							System.Drawing.Image image = System.Drawing.Image.FromStream(fs);
							newMedia.getProperty("umbracoWidth").Value = image.Width.ToString();
							newMedia.getProperty("umbracoHeight").Value = image.Height.ToString();

							// Generate thumbnails
							string fileNameThumb = Server.MapPath("/media") + "\\" + newName.Replace(Path.GetExtension(theEntry.Name), "_thumb");
							generateThumbnail(image, 100, image.Width, image.Height, Server.MapPath("/media/" + newName), Path.GetExtension(theEntry.Name), fileNameThumb + ".jpg");

							if (_thumbnails != "")
							{
								string[] thumbnailSizes = _thumbnails.Split(";".ToCharArray());
								foreach(string thumb in thumbnailSizes)
									if (thumb != "")
										generateThumbnail(image, int.Parse(thumb), image.Width, image.Height, Server.MapPath("/media/" + newName), Path.GetExtension(theEntry.Name), fileNameThumb + "_" + thumb + ".jpg");
							}

							image.Dispose();

							fs.Close();
							/*
													// Bugfix - 2006.06.22 - thumbnails don't keep the aspect ratio when saving..
													// Generate thumbnail
													string fileNameThumb = Server.MapPath("/media") + "\\" + newName.Replace(Path.GetExtension(theEntry.Name), "_thumb.jpg");
													using(System.Drawing.Image image = System.Drawing.Image.FromFile(Server.MapPath("/media") + "\\" + newName))
													{
														// subsampling factors
														float fx = image.Width / 100;
														float fy = image.Height / 100; 

														// must fit in thumbnail size
														float f=Math.Max(fx,fy); if(f<1) f=1;

														// calculate thumb height and width
														int widthTh = (int)(image.Width / f); 
														int heightTh = (int)(image.Height / f);

														using(Bitmap bitmap = new Bitmap(image, widthTh, heightTh)) 
														{
															bitmap.Save(fileNameThumb, ImageFormat.Jpeg);
														}
													}
													// End Bugfix
							*/
						}
					} 
					catch (Exception ee) 
					{
						umbraco.BusinessLogic.Log.Add(umbraco.BusinessLogic.LogTypes.Error, u, newMedia.Id, "Error creating thumbnail: " + ee.ToString());
					}

				}
			}

			// Clean up
			s.Close();
			Directory.Delete(tempDir, false);
			File.Delete(zipName);

			// Show status
			Panel1.Visible = false;
			Panel2.Visible = true;
			Literal1.Text = "<b>Files uploaded:</b><br/>" + uploaded;
		}

		private void generateThumbnail(System.Drawing.Image image, int maxWidthHeight, int fileWidth, int fileHeight, string fullFilePath, string ext, string thumbnailFileName)
		{
			// Generate thumbnail
			float fx = fileWidth / maxWidthHeight;
			float fy = fileHeight / maxWidthHeight; // subsampling factors
			// must fit in thumbnail size
			float f = Math.Max(fx, fy); if (f < 1) f = 1;
			int widthTh = (int)(fileWidth / f); int heightTh = (int)(fileHeight / f);

			// Create new image with best quality settings
			Bitmap bp = new Bitmap(widthTh, heightTh);
			Graphics g = Graphics.FromImage(bp);
			g.SmoothingMode = SmoothingMode.HighQuality;
			g.InterpolationMode = InterpolationMode.HighQualityBicubic;
			g.PixelOffsetMode = PixelOffsetMode.HighQuality;

			// Copy the old image to the new and resized
			Rectangle rect = new Rectangle(0, 0, widthTh, heightTh);
			g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);

			// Copy metadata
			ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
			ImageCodecInfo codec = null;
			for (int i = 0; i < codecs.Length; i++)
			{
				if (codecs[i].MimeType.Equals("image/jpeg"))
					codec = codecs[i];
			}

			// Set compresion ratio to 90%
			EncoderParameters ep = new EncoderParameters();
			ep.Param[0] = new EncoderParameter(Encoder.Quality, 90L);

			// Save the new image
			bp.Save(thumbnailFileName, codec, ep);
			bp.Dispose();
			g.Dispose();
            
		}
		
	}
}
